using System;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Pegasus.UnitTests.Runtime.Serialization.Formatters.Xml.XmlFormatter2Tests
{
	/// <summary>
	/// This is a test class for Pegasus.Runtime.Serialization.Formatters.Xml.XmlFormatter2
	/// and will check the basic types support.
	///</summary>
	[TestClass]	
	public class XmlFormatter2BasicTypesTests
	{
		// Local Instance Values
		private TestContext m_testContextInstance;

		/// <summary>
		/// Initializes a new instance of the <see cref="T:XmlFormatter2TestBasicTypesTests"/> class.
		/// </summary>
		public XmlFormatter2BasicTypesTests()
		{
		}

		/// <summary>
		/// Gets or sets the test context which provides information about and 
		/// functionality for the current test run.
		/// </summary>
		/// <value>The test context.</value>
		public TestContext TestContext
		{
			get
			{
				return m_testContextInstance;
			}
			set
			{
				m_testContextInstance = value;
			}
		}

		/// <summary>
		/// Test the Serialize of boolean type.
		/// </summary>
		[TestMethod]
		public void SerializeBoolTest()
		{
			Assert.IsTrue( (bool) XmlFormatter2Helper.SerializeDeserialize( true ), "Boolean true did not serialize correctly" );
			Assert.IsFalse( (bool) XmlFormatter2Helper.SerializeDeserialize( false ), "Boolean false did not serialize correctly" );
		}

		/// <summary>
		/// Test the Serialize of char type.
		/// </summary>
		[TestMethod]
		public void SerializeCharTest()
		{
			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( 'A' ), 'A', "Char A did not serialize correctly" );
			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( 'Z' ), 'Z', "Char Z did not serialize correctly" );
			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( 'a' ), 'a', "Char 1 did not serialize correctly" );
			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( 'z' ), 'z', "Char z did not serialize correctly" );

			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( '1' ), '1', "Char 1 did not serialize correctly" );
			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( '0' ), '0', "Char 0 did not serialize correctly" );
			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( '!' ), '!', "Char ! did not serialize correctly" );
			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( '^' ), '^', "Char ^ did not serialize correctly" );
			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( '*' ), '*', "Char * did not serialize correctly" );

			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( '<' ), '<', "Char < did not serialize correctly" );
			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( '>' ), '>', "Char > did not serialize correctly" );
			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( '&' ), '&', "Char & did not serialize correctly" );
			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( ';' ), ';', "Char ; did not serialize correctly" );

			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( ' ' ), ' ', "Char Space did not serialize correctly" );
			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( '\n' ), '\n', "Char CR did not serialize correctly" );
			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( '\t' ), '\t', "Char Tab did not serialize correctly" );

			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( '\u03B1' ), '\u03B1', "Char \u03B1 did not serialize correctly" );
			Assert.AreEqual( (char) XmlFormatter2Helper.SerializeDeserialize( '\u03A9' ), '\u03A9', "Char \u03A9 did not serialize correctly" );
		}

		/// <summary>
		/// Test the Serialize of sbyte type.
		/// </summary>
		[TestMethod]
		public void SerializeSByteTest()
		{
			sbyte interval = ( sbyte.MaxValue - sbyte.MinValue ) / XmlFormatter2Helper.TestLoops;
			sbyte value = sbyte.MinValue;

			for( int x = 0; x < XmlFormatter2Helper.TestLoops; x++ )
			{
				Assert.AreEqual( (sbyte) XmlFormatter2Helper.SerializeDeserialize( value ), value, "SByte {0} did not serialize correctly", value );
				value += interval;
			}
		}

		/// <summary>
		/// Test the Serialize of byte type.
		/// </summary>
		[TestMethod]
		public void SerializeByteTest()
		{
			byte interval = ( byte.MaxValue - byte.MinValue ) / XmlFormatter2Helper.TestLoops;
			byte value = byte.MinValue;

			for( int x = 0; x < XmlFormatter2Helper.TestLoops; x++ )
			{
				Assert.AreEqual( (byte) XmlFormatter2Helper.SerializeDeserialize( value ), value, "Byte {0} did not serialize correctly", value );
				value += interval;
			}
		}

		/// <summary>
		/// Test the Serialize of short type.
		/// </summary>
		[TestMethod]
		public void SerializeShortTest()
		{
			short interval = ( short.MaxValue - short.MinValue ) / XmlFormatter2Helper.TestLoops;
			short value = short.MinValue;

			for( int x = 0; x < XmlFormatter2Helper.TestLoops; x++ )
			{
				Assert.AreEqual( (short) XmlFormatter2Helper.SerializeDeserialize( value ), value, "Short {0} did not serialize correctly", value );
				value += interval;
			}
		}

		/// <summary>
		/// Test the Serialize of ushort type.
		/// </summary>
		[TestMethod]
		public void SerializeUShortTest()
		{
			ushort interval = ( ushort.MaxValue - ushort.MinValue ) / XmlFormatter2Helper.TestLoops;
			ushort value = ushort.MinValue;

			for( int x = 0; x < XmlFormatter2Helper.TestLoops; x++ )
			{
				Assert.AreEqual( (ushort) XmlFormatter2Helper.SerializeDeserialize( value ), value, "UShort {0} did not serialize correctly", value );
				value += interval;
			}
		}

		/// <summary>
		/// Test the Serialize of int type.
		/// </summary>
		[TestMethod]
		public void SerializeIntTest()
		{
			int interval = (int) ( ( (long) int.MaxValue - (long) int.MinValue ) / (long) XmlFormatter2Helper.TestLoops );
			int value = int.MinValue;

			for( int x = 0; x < XmlFormatter2Helper.TestLoops; x++ )
			{
				Assert.AreEqual( (int) XmlFormatter2Helper.SerializeDeserialize( value ), value, "Int {0} did not serialize correctly", value );
				value += interval;
			}
		}

		/// <summary>
		/// Test the Serialize of uint type.
		/// </summary>
		[TestMethod]
		public void SerializeUIntTest()
		{
			uint interval = ( uint.MaxValue - uint.MinValue ) / XmlFormatter2Helper.TestLoops;
			uint value = uint.MinValue;

			for( int x = 0; x < XmlFormatter2Helper.TestLoops; x++ )
			{
				Assert.AreEqual( (uint) XmlFormatter2Helper.SerializeDeserialize( value ), value, "UInt {0} did not serialize correctly", value );
				value += interval;
			}
		}

		/// <summary>
		/// Test the Serialize of long type.
		/// </summary>
		[TestMethod]
		public void SerializeLongTest()
		{
			long interval = (long) ( ( (long) int.MaxValue - (long) int.MinValue ) / (long) XmlFormatter2Helper.TestLoops );
			long value = long.MinValue;

			for( long x = 0; x < XmlFormatter2Helper.TestLoops; x++ )
			{
				Assert.AreEqual( (long) XmlFormatter2Helper.SerializeDeserialize( value ), value, "Long {0} did not serialize correctly", value );
				value += interval;
			}
		}

		/// <summary>
		/// Test the Serialize of ulong type.
		/// </summary>
		[TestMethod]
		public void SerializeULongTest()
		{
			ulong interval = ( ulong.MaxValue - ulong.MinValue ) / XmlFormatter2Helper.TestLoops;
			ulong value = ulong.MinValue;

			for( long x = 0; x < XmlFormatter2Helper.TestLoops; x++ )
			{
				Assert.AreEqual( (ulong) XmlFormatter2Helper.SerializeDeserialize( value ), value, "ULong {0} did not serialize correctly", value );
				value += interval;
			}
		}

		/// <summary>
		/// Test the Serialize of float type.
		/// </summary>
		[TestMethod]
		public void SerializeFloatTest()
		{
			float interval = ( float.MaxValue - float.MinValue ) / XmlFormatter2Helper.TestLoops;
			float value = float.MinValue;

			for( long x = 0; x < XmlFormatter2Helper.TestLoops; x++ )
			{
				Assert.AreEqual( (float) XmlFormatter2Helper.SerializeDeserialize( value ), value, "Float {0} did not serialize correctly", value );
				value += interval;
			}
		}

		/// <summary>
		/// Test the Serialize of double type.
		/// </summary>
		[TestMethod]
		public void SerializeDoubleTest()
		{
			double interval = ( double.MaxValue - double.MinValue ) / XmlFormatter2Helper.TestLoops;
			double value = double.MinValue;

			for( long x = 0; x < XmlFormatter2Helper.TestLoops; x++ )
			{
				Assert.AreEqual( (double) XmlFormatter2Helper.SerializeDeserialize( value ), value, "Double {0} did not serialize correctly", value );
				value += interval;
			}
		}

		/// <summary>
		/// Test the Serialize of decimal type.
		/// </summary>
		[TestMethod]
		public void SerializeDecimalTest()
		{
			// Can not load the full value (max - min) for decimal into given memory so
			// just use the twice the max value.
			decimal interval = ( decimal.MaxValue / ( XmlFormatter2Helper.TestLoops + 1 ) ) * 2;
			decimal value = decimal.MinValue;

			for( long x = 0; x < XmlFormatter2Helper.TestLoops; x++ )
			{
				Assert.AreEqual( (decimal) XmlFormatter2Helper.SerializeDeserialize( value ), value, "Decimal {0} did not serialize correctly", value );
				value += interval;
			}
		}

		/// <summary>
		/// Test the Serialize of datetime type.
		/// </summary>
		[TestMethod]
		public void SerializeStringTest()
		{
            // String that is null
            string str = null;
            Assert.AreEqual( (string) XmlFormatter2Helper.SerializeDeserialize( str ), str, "Null String did not serialize correctly" );

            // String that is empty
            str = string.Empty;
            Assert.AreEqual( (string) XmlFormatter2Helper.SerializeDeserialize( str ), str, "String \"{0}\"did not serialize correctly", str );

			for( long x = 0; x < 10; x++ )
			{
				char setA = (char) ( x + 0x0041 ); // Latin capital letters
				char setB = (char) ( x + 0x0061 ); // Laten small letters
				char setC = (char) ( x + 0x0391 ); // Greek capital letters
				char setD = (char) ( x + 0x03B1 ); // Greek small letters
				char setE = (char) ( x + 0x0401 ); // Cytillic capital letters
				char setF = (char) ( x + 0x0431 ); // Cytillic small letters

				str = "This is a string with unicode chars in it. " + setA + setB + setC + setD + setE + setF;
				Assert.AreEqual( (string) XmlFormatter2Helper.SerializeDeserialize( str ), str, "String \"{0}\"did not serialize correctly", str );

				// String with 10 spaces at the front and back
				str = "          " + setA + setB + setC + setD + setE + setF + "          ";
				Assert.AreEqual( (string) XmlFormatter2Helper.SerializeDeserialize( str ), str, "String \"{0}\"did not serialize correctly", str );

				// String with escape chars at the front and back
				str = "\t\t\r\n\r\n&&&<<<" + setA + setB + setC + setD + setE + setF + ">>>&&&\t\t\r\n\r\n";
				Assert.AreEqual( (string) XmlFormatter2Helper.SerializeDeserialize( str ), str, "String \"{0}\"did not serialize correctly", str );
			}
		}
	}
}
